home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d13
/
pb_c.arc
/
TBC2PB
< prev
Wrap
Text File
|
1991-01-23
|
9KB
|
239 lines
Date: 15-Jan-91 15:39 PST
From: Kurt Inman [71141,2330]
Subj: pb links tc now
Bob,
I finally found a way to link TC routines into PB programs! If you use
the Huge model (code & data segments of any size, including multiple
segments) to compile the C code, it only generates a code segment and
a data segment to the .OBJ file, rather than including the BSS segment
which PB was tripping up on. Here's how to do it explicitly:
1. Set Options/Compiler/Model to Huge.
2. Set Options/Compiler/Names/Code names/Segment name to CSEG.
3. Set Options/Compiler/Names/Code names/Class name to nothing (it
defaults to '*').
4. Set Options/Compiler/Names/Data names/Segment name to DSEG.
5. Set Options/Compiler/Names/Data names/Class name to nothing (it
defaults to '*').
6. Compile your code (you don't need to change any Group names or
BSS names, nor do you have to Options/Linker/Initialize segments).
7. $LINK the .OBJ module into your PB program as usual.
Kurt
15-Jan-91 20:19:29
Sb: #Using TC with PB
Fm: Kurt Inman (PowerBASIC) 71141,2330
To: All
We've identified a problem which occurs when you attempt to $LINK an .OBJ file
created with Borland's Turbo C compiler into a PowerBASIC program. Many
combinations of Turbo C models and segment names in the .OBJ file will cause PB
to generate either Error 510 (Code requires byte alignment) or Error 509
(Invalid segment name) on the $LINK metastatement. In fact, the Error 510 is
incorrect in this case, and is generated regardless of whether the code is
byte-aligned or not.
The cause of the Error 510/509 is that for all memory models except Huge, Turbo
C creates definitions for three segments in the .OBJ file: code (_TEXT),
initialized data (_DATA), and uninitialized data (_BSS). Even if you force
Turbo C to use the same name for both data segments, it will still place three
segment definitions in the .OBJ file, causing PowerBASIC to generate Error
510/509 when it encounters a second data segment definition.
The solution is to compile your Turbo C code using the Huge memory model, with
the code segment named CSEG and the data segment named DSEG. You must also
explicitly tell TC not to generate a class name for either segment. Using the
Huge model causes TC to generate definitions for only one code and one data
segment, both without group names. This is the only configuration which fully
conforms to PB's method of linking external routines.
Here are the steps to use when compiling your routines with Turbo C version
2.0. Borland's Turbo C++ compiler may also generate PB-compatible code if the
corresponding code generation options are enabled.
1. Set Options/Compiler/Model to Huge.
2. Set Options/Compiler/Names/Code names/Segment name to CSEG.
3. Set Options/Compiler/Names/Code names/Class name to nothing
(it defaults to '*').
4. Set Options/Compiler/Names/Data names/Segment name to
DSEG.
5. Set Options/Compiler/Names/Data names/Class name to nothing (it
defaults to '*').
6. Compile your code to an .OBJ file (you don't need to
change any Group names or BSS names, nor do you have to
Options/Linker/Initialize segments).
7. $LINK the resulting .OBJ file into your PB program.
To: All
(continued from previous "Using TC with PB" message)
Please let us know if there are any problems with this method. It works
in the limited cases that we've tried, but we haven't tested it exhaustively.
We are posting it in an effort to assist those of you who need to link your
Turbo C routines into PowerBASIC programs.
Kurt Inman (PowerBASIC R&D)
Sb: #87182-Using TC with PB
Fm: AL MUSELLA 76114,637
To: Kurt Inman (PowerBASIC) 71141,2330
Kurt,
I tried this and got rid of the byte alignment problem, but I am now having
difficulty getting pb to recognize the c functions. I get error 462"undefined
sub/fn". I tried declare function - no help!
Can you give a short example on how to pass an integer (and maybe a string)
to a c function? Both the c code and pb code.
BTW - you have to use tcinst to change the names of the groups in TC++,
unlike tc2.0, where you can change them from the enviorment.
Al
16-Jan-91 10:13:32
Sb: #87182-#Using TC with PB
Fm: AL MUSELLA 76114,637
To: Kurt Inman (PowerBASIC) 71141,2330 (X)
Kurt,
I finally got a c .obj to work with pb! The trick was to turn off the
generate underbars option. There is still a problem with passing parameters
though, and if you could demonstrate just passing integers back and forth, it
would be a big help.
Al
There is 1 Reply.
16-Jan-91 13:55:26
Sb: #87261-Using TC with PB
Fm: Kurt Inman (PowerBASIC) 71141,2330
To: AL MUSELLA 76114,637
Al,
Here's a simple example of a C function which takes an integer as a parameter,
adds 17 to it, and returns it to the PB program:
TC:
/* compile this to MYCCODE.OBJ as per my last message */
int pascal DOCALC (int far *pbvar)
{
return (*pbvar)+17;
}
PB:
$link "myccode.obj"
declare function DOCALC%(integer)
print DOCALC%(5) 'prints 22 (5+17)
Some things to note: the C function is declared to use PASCAL calling
conventions (the C function must clean up the stack after the call, not PB),
the parameter PBVAR is declared to be a far pointer to an integer since PB
passes all parameters as far pointers, the function has a return type of INT
which causes the returned integer to be placed in the AX register upon return
(which is what PB expects of an external function that returns an integer), and
PB's DECLARE statement must explicitly specify that the C function is an
integer function which takes an integer as a parameter. I'll put up an example
with strings shortly.
Kurt
Sb: #87307-#Using TC with PB
Fm: Kurt Inman (PowerBASIC) 71141,2330
To: Kurt Inman (PowerBASIC) 71141,2330 (X)
Al,
Here's a simple example of a C routine which changes the first character of a
PB string which is passed to it as a parameter:
TC:
/* compile as MYCCODE.OBJ as per my earlier message */
#include <dos.h>
void pascal DOSTR(unsigned far *stseg, unsigned far *stofs, int far *stlen)
{
char far *stdata; /* will point to actual string data */
if (*stlen) { /* if string length > 0 */
stdata = (char far *) MK_FP(*stseg, *stofs); /* get data pointer */
if (stdata) /* if valid string */
*stdata = '*'; /* change 1st char of string to '*' */
}
}
PB:
$link "myccode.obj"
declare sub DOSTR(integer,integer,integer)
a$="hello"
call DOSTR(strseg(a$),strptr(a$),len(a$)) 'pass segment/offset/length
print a$ 'will print "*ello"
Keep in mind that the C routine must not change the length of the string passed
to it. Also, this example works for both regular and flex strings. Hope this
helps!
Kurt
There is 1 Reply.
16-Jan-91 17:19:43
Sb: #87316-#Using TC with PB
Fm: AL MUSELLA 76114,637
To: Kurt Inman (PowerBASIC) 71141,2330 (X)
Kurt,
Thanks very much for the help. Your sample programs worked fine.
One more question - (although I think this is impossible):
I was trying to link in the TC BGI routines, to allow my PB programs to use
different fonts. I used tlib to convert the needed routines from the graphics
library into .obj files, but the segment names won't work with PB. Is there
any way to fix that?
I found a strange way around it, but it's very clutzy:
I set up an interrupt handler (using 60h) in C, which when called from pb using
call interrupt, would print a (constant) string in the correct font. Now that
you showed me how to pass variables, this may actually be useful!
One last note: I made a mistake in my last message: You can set the segment
names from the tc++ enviorment, they are just in a different place on the menu
than in tc.
Thanks again,
Al
PS: You should include those 2 examples in the next edition of the manual for
PB!
There is 1 Reply.
16-Jan-91 17:53:08
Sb: #87351-Using TC with PB
Fm: Kurt Inman (PowerBASIC) 71141,2330
To: AL MUSELLA 76114,637
Al,
I think the only way around the problem with the BGI segment names would be to
attempt to directly modify the .OBJ files, in order to change the names to
something that PB could accept. That would be very messy and may not even be
possible depending on the lengths of the names used, etc. Maybe PB will be able
to handle more segment names in the future, or we or some third party will
develop a graphics library for PB similar to BGI. For now, though, I don't see
any way around the problem, short of a real kludge.
I think we will put the C examples in the next manual (or at least the next
README file) -- that's a good idea!
Kurt